#ifndef POLLSCHEDULER_H
#define POLLSCHEDULER_H

#include <QObject>
#include <QThread>
#include <QTimer>
#include <QVector>
#include <QMap>
#include "modbusmaster.h"
#include "serialportmanager.h"
#include "../core/meter.h"

/**
 * @brief 单条总线轮询工作线程
 * 负责在独立线程中轮询单条总线上的所有电表
 */
class BusPollerThread : public QThread
{
    Q_OBJECT

public:
    explicit BusPollerThread(int busId, QSerialPort *serialPort,
                             const QVector<Meter *> &meters, QObject *parent = nullptr);
    ~BusPollerThread();

    /**
     * @brief 设置轮询间隔
     * @param interval 轮询间隔（毫秒）
     */
    void setPollInterval(int interval);

    /**
     * @brief 停止轮询
     */
    void stopPolling();

signals:
    /**
     * @brief 轮询周期完成信号
     * @param busId 总线ID
     * @param successCount 成功轮询的电表数
     * @param totalCount 总电表数
     */
    void pollCycleCompleted(int busId, int successCount, int totalCount);

    /**
     * @brief 电表数据批量更新信号（轮询周期结束后发送）
     * @param meterIds 已更新的电表ID列表
     */
    void meterDataBatchUpdated(const QVector<int> &meterIds);

    /**
     * @brief 电表数据需要采样存储信号（每5分钟触发一次）
     * @param meterId 电表ID
     * @param meter 电表对象指针
     */
    void meterDataSampled(int meterId, Meter *meter);

protected:
    void run() override;

private:
    int m_busId;                           ///< 总线ID
    QSerialPort *m_serialPort;             ///< 串口对象（从主线程移动到工作线程）
    ModbusMaster *m_modbusMaster;          ///< Modbus主站对象（在工作线程创建）
    QVector<Meter *> m_meters;             ///< 电表列表
    int m_pollInterval;                    ///< 轮询间隔（毫秒）
    bool m_running;                        ///< 运行标志
    QMap<int, QDateTime> m_lastSampleTime; ///< 每个电表的最后采样时间
    QVector<int> m_updatedMeterIds;        ///< 本轮已更新的电表ID列表
};

/**
 * @brief 轮询调度器类
 * 管理3条总线的并行轮询
 *
 * @note 生命周期说明：
 * - PollScheduler 只借用 SerialPortManager 提供的串口，不管理串口生命周期
 * - 必须确保 SerialPortManager 的生命周期长于 PollScheduler
 * - 析构顺序：PollScheduler 先析构 → SerialPortManager 后析构
 */
class PollScheduler : public QObject
{
    Q_OBJECT

public:
    explicit PollScheduler(SerialPortManager *portManager, QObject *parent = nullptr);
    ~PollScheduler();

    /**
     * @brief 添加总线配置
     * @param busId 总线ID（1-3）
     * @param portName 串口名称
     * @param meters 该总线上的电表列表
     * @return 是否添加成功
     */
    bool addBus(int busId, const QString &portName, const QVector<Meter *> &meters);

    /**
     * @brief 设置轮询间隔
     * @param interval 轮询间隔（毫秒），默认500ms
     */
    void setPollInterval(int interval);

    /**
     * @brief 启动轮询
     */
    void startPolling();

    /**
     * @brief 停止轮询
     */
    void stopPolling();

    /**
     * @brief 获取轮询状态
     * @return 是否正在轮询
     */
    bool isPolling() const { return m_polling; }

signals:
    /**
     * @brief 轮询启动信号
     */
    void pollingStarted();

    /**
     * @brief 轮询停止信号
     */
    void pollingStopped();

    /**
     * @brief 总线轮询周期完成信号
     * @param busId 总线ID
     * @param successCount 成功数
     * @param totalCount 总数
     */
    void busPollCompleted(int busId, int successCount, int totalCount);

    /**
     * @brief 电表数据批量更新信号（转发自线程，用于UI刷新）
     * @param meterIds 已更新的电表ID列表
     */
    void meterDataBatchUpdated(const QVector<int> &meterIds);

    /**
     * @brief 电表数据采样信号（转发自线程，用于数据存储）
     * @param meterId 电表ID
     * @param meter 电表对象指针
     */
    void meterDataSampled(int meterId, Meter *meter);

private slots:
    /**
     * @brief 处理总线轮询周期完成
     */
    void onPollCycleCompleted(int busId, int successCount, int totalCount);

private:
    SerialPortManager *m_portManager;          ///< 串口管理器
    QMap<int, BusPollerThread *> m_busThreads; ///< 总线轮询线程映射
    int m_pollInterval;                        ///< 轮询间隔
    bool m_polling;                            ///< 轮询状态
};

#endif // POLLSCHEDULER_H
